
今天要來做的是圖片模糊加載,圖片一開始是很模糊的,隨著加載率從0%~100%的過程中,會越來越清楚,最後進入焦點,而加載文字的部分則會慢慢淡出
1.一張你喜歡的圖片,要做為背景用
| 知識點 | 使用說明 | 
|---|---|
| Background 背景 | 設定背景圖片格式 | 
| Filter濾鏡效果 | 圖片的模糊處理 | 
| calc() 計算函數 | 計算模糊範圍 | 
| 知識點 | 使用說明 | 
|---|---|
| querySelector() | 獲取HTML元素 | 
| setInterval() / clearInterval() | 抓取加載%數的範圍 | 
| innerText | 把加載文字渲染在畫面上 | 
 <div class="bg"></div>
    <!-- 加載文字-->
    <div class="loading-text">0%</div>
div.bg {
/* <background-image> <background-repeat> <background-position> / <background-size>*/
  background: url("...") no-repeat 50% 50% / cover;
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
  filter: blur(30px);
}
background是有關背景圖片的各個屬性集合,關於background的順序並沒有一個很明確的標準,可以參考stackoverflow上的這篇文章
background-position設為50% 50%也等於center center,如果兩個值都一樣,可以只寫一個background-position和background-size之間會用『/』去區隔彼此
這裡主要就是設定背景圖片的大小、位子...,並利用filter:blur(PX)去做模糊效果,數字越大越模糊,如果沒有填入,預設是0
加載文字
.loading-text {
  font-size: 50px;
  color: white;
}
若以上都設定好呈現如下,好像沒有戴上眼鏡的世界一樣模糊
不過我們會看到周圍會有一圈白邊,如果我想要讓白邊的範圍不要那麼大,稍微內縮,可以怎麼做呢??
以下程式碼只擷取有修改過的部分,我們為了把白邊範圍內縮一點,所以把top和left設定為"負數",所以它就會往視窗上方以及左方移動,這點應該沒有問題,不過如果只設這樣並不夠,那我右邊和下面的白框還是沒有內縮啊~該怎麼辦呢?
其實有兩種解法,第一種就是很直覺的把right和bottom設為-30px,不過還有更精簡的寫法,就是底下這種寫法
calc取自英文calculator的前面四個字,意思是計算,所以 calc(mathematical  expression)通常拿來做數值的運算,而且運算的數值"不需要"相同單位,我可以「 px + % 」或是「 % - px - em」等,彈性相當大,不過若運算子中間沒有空格格開(如:「 px+% 」),整個效果就會不見,這也是我在實作的過程意外發現的bug
div.bg {
  top: -30px;
  left: -30px;
  width: calc(100vw + 60px);
  height: calc(100vh + 60px);
}
let loadText = document.querySelector(".loading-text");
let bg = document.querySelector(".bg");
let load = 0;
let int = setInterval(blurring, 30); //每30毫秒執行一次blurring這個函式
function blurring() {
  load++;
  console.log(load);
  
    //記得clearInterval()
    if (load > 99) {
      clearInterval(int);
    }
}
你可以試著把clearInterval()註解看看,打開Dev tool就會看到一串無限的數字再跑 @ @ ,所以務必要記得clearInterval()!!這樣一來它的範圍只會被我們限縮在0~100,而我們要利用這個結論去讓加載文字可以從0%~100%去跑
繼續加上下面這一段,我們要把剛剛load的數字渲染到畫面上
 loadText.innerText = `${load}%`;
呈現會如下圖,算是完成1/3了
我們在最一開始的完成版看到,隨著加載率的上升,除了圖片越來越清楚外,%數則會慢慢淡出,接下來我們要來實作%數慢慢淡出這一段
這可以說是此賽pjoject的重頭戲,參考了sackoverflow上的一篇文章來完成,它是一個要把一個數字範圍應設到另一個數字範圍的function,恩..聽不懂沒關係,直接看底下程式碼更清楚,這用法也是我第一次看到,先附上stackoverflow的文章map a range of numbers to another range of numbers
%數的淡出
0% ➔ opacity:1;
100% ➔ opacity:0;
利用opacity去控制
loadText.style.opacity = scale(load, 0, 100, 1, 0); //加載數字(load)0-100的透明度為1-0
  // 以下取自stackoverflow
  function scale(number, inMin, inMax, outMin, outMax) {
    return ((number - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
  }
設定好後,呈現如下,我們讓數字慢慢淡出了,完成2/3了ヽ(✿゚▽゚)ノ
圖片的模糊程度
跟%數的淡出其實是同理
 bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)`;//加載數字(load)0-100的圖片的模糊程度為blur(30px)➔blur(0px)
若以上都設定好,就全部完成啦~
在此附上codepen連結 https://codepen.io/hangineer/pen/zYjqMMj
另外也可以不使用stackoverflow的那個function,有更簡潔的方法
圖片取自50 Projects In 50 Days - HTML, CSS & JavaScript FAQ
本篇用到了calc()、setInterval() 與 clearInterval()、數字範圍變化的function等,各個知識點的釐清很重要,另外也在底下補充了一些常混淆的觀念
[補充]
談談 JavaScript 的 setTimeout 與 setInterval
JavaScript innerHTML 與 innerText 的差異
關於javaScript的Expression和Statement
若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!明天見
50 Projects In 50 Days - HTML, CSS & JavaScript
CSS Background-position
w3School CSS filter
map a range of numbers to another range of numbers
[補充]
設在背景圖片中的 filter: blur(30px); 是可以省略的
因為後來透過以下這段javaScript去控制了
// 圖片的模糊程度
  bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px
  
  function scale(number, inMin, inMax, outMin, outMax) {
    return ((number - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
  }